/*
 * HDLCProtocol.h
 *
 *  Created on: 5 nov. 2010
 *      Author: eric
 */

#ifndef HDLCPROTOCOL_H_
#define HDLCPROTOCOL_H_

#include <Arduino.h>

#include "crc16.h"
#include "Can.h"

class HDLCProtocol {
	static uint8_t const FRAME_BOUNDARY = 0x7E;//126
	static uint8_t const ESCAPE_OCTET = 0x7D;//125
	static uint8_t const ESCAPEXOR_FLAG = 0x20;//32

	static uint8_t const I_FRAME_BITS = 0x1;//1
	static uint8_t const S_FRAME_BITS = 0x3;//3

	static uint8_t const S_FRAME_RR = 0x11;//17
	static uint8_t const S_FRAME_RNR = 0x15;//21
	static uint8_t const S_FRAME_REJ = 0x19;//25

	static uint8_t const U_FRAME_UA = 0x73;//115
	static uint8_t const U_FRAME_SABM = 0x3F;//63
	static uint8_t const U_FRAME_DISC = 0x53;//83
	static uint8_t const U_FRAME_DM = 0x1F;//31
	static uint8_t const U_FRAME_TEST = 0x33;//51

	static uint8_t const I_FRAME_DATA = 0x0;//0

	uint8_t lastControlByte;

	typedef CRC16_ccitt::crc_t CRC;
	uint8_t pBufPtr;
	static uint8_t const maxPacketSize = 32;
	uint8_t pBuf[maxPacketSize];
	bool linkUp;
	bool inPacket;
	bool unEscaping;
	CRC16_ccitt incrc, outcrc;
	void setLinkDown();
	void setLinkUp();
	void disconnect();
	void sendByte(uint8_t byte);
	void startPacket();
	void sendPreamble();
	void sendPostamble();
	void sendData(const uint8_t * const buf, uint8_t size);
	void sendData(uint8_t c);
	void processFrame();
	void sendFrame(uint8_t const command, Can::CAN_MSG canMsg);
	void sendFrame(uint8_t const command);
	void handleInformationFrame(uint8_t *pBuf);
	void handleUnnumberedFrame(uint8_t *pBuf);
	void handleSupervisoryFrame(uint8_t *pBuf);
public:
	uint8_t processData(uint8_t bIn);
	void startXMit();
};

#endif /* HDLCPROTOCOL_H_ */
